package org.hrhr74.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.hrhr74.entity.*;
import org.hrhr74.entity.dto.UserDTO;
import org.hrhr74.mapper.UserMapper;
import org.hrhr74.service.IUserService;
import org.hrhr74.utils.PasswordEncoder;
import org.hrhr74.utils.RegexUtils;
import org.hrhr74.utils.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.hrhr74.constant.RedisConstant.*;
import static org.hrhr74.constant.UserConstants.PREFIX_USERNAME;

@Service
@Slf4j
public class UserServiceImpl implements IUserService {
    /**
     * 发送验证码
     * @param phone
     * @param session
     * @return
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserMapper userMapper;

    // 日期时间格式化器（匹配MySQL的DATETIME格式）
    private static final DateTimeFormatter DATETIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");



   // private String tokenTemp = "";

    @Override
    public Result sendCode(String phone, HttpSession session) {
        //校验手机号
        if(RegexUtils.isPhoneInvalid(phone)){
           return Result.error("手机格式不正确！！！");
        }

        //生成验证码
        String code = RandomUtil.randomNumbers(6);
        //将验证码保存到redis中，方便后续验证
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);
        //发送验证码
        log.info("demo-ai：您的验证码为"+code+"(5分钟内有效)");
        return Result.success();
    }

    /**
     * 手机验证码登录
     * @param login
     * @param session
     * @return
     */
    @Override
    public Result login_code(LoginCode login, HttpSession session) {
        String phone = login.getPhone();
        //验证手机号格式
        if(RegexUtils.isPhoneInvalid(phone)){
            return Result.error("手机格式不正确！！");
        }
        //验证验证码
        String CacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);//获取redis中的验证码
        String code = login.getCode();//前端用户输入的验证码
        if(CacheCode == null || !CacheCode.equals(code)){
            //验证码不存在（或已过期）或者验证码不匹配
            return Result.error("验证码不存在或有误！");
        }
        //根据手机号查询用户是否存在
        User user = userMapper.getByPhone(phone);
        if(user == null){
            //不存在添加用户信息至数据库
            createUserByPhone(phone);
        }
        //将用户信息保存到redis(使用hash存储)
        String token = UUID.randomUUID().toString(true);//设置一个token
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        String redisToken = LOGIN_USER_KEY + token;
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor(
                        (filedName, filedValue) ->{
                            if(filedValue == null){
                                return "";
                            }
                            if (filedValue instanceof LocalDateTime) {
                                return ((LocalDateTime) filedValue).format(DATETIME_FORMATTER);
                            }
                            return filedValue.toString();
                        }
                       ));
        stringRedisTemplate.opsForHash().putAll(redisToken,userMap);
        //设置token的有效期
        stringRedisTemplate.expire(redisToken,LOGIN_USER_TTL,TimeUnit.MINUTES);
        //将token返回前端
        return Result.success(token);
    }



    /**验证码注册时创建用户逻辑
     *
     * @param phone
     * @return
     */
    public User createUserByPhone(String phone){
        User user = new User();
        user.setPhone(phone);
        user.setUsername(PREFIX_USERNAME + RandomUtil.randomNumbers(6));
        userMapper.saveUserByPhone(user);
        return user;
    }

    /**账号密码登录
     *
     */
    @Override
    public Result login_password(LoginPassword login, HttpSession session) {
        Long account = login.getAccount();
        String password = login.getPassword();
        User user = userMapper.getUserByAccount(account);
        //判断是否有该账户
        if (user == null) {
            return Result.error("该用户不存在！");
        }
        //校验密码
        String userPassword = user.getPassword();
        if(!PasswordEncoder.matches(userPassword,password)){
            return Result.error("密码不匹配！");
        }
        String token = UUID.randomUUID().toString(true);//设置一个token
        String redisToken = LOGIN_USER_KEY + token;
        //将token保存下来，方便使用

        //将用户信息保存到redis(使用hash存储)
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor(
                        (filedName, filedValue) ->{
                            if(filedValue == null){
                                return "";
                            }
                            if (filedValue instanceof LocalDateTime) {
                                return ((LocalDateTime) filedValue).format(DATETIME_FORMATTER);
                            }
                            return filedValue.toString();
                        }
                ));
        stringRedisTemplate.opsForHash().putAll(redisToken,userMap);
        //设置token的有效期
        stringRedisTemplate.expire(redisToken,LOGIN_USER_TTL,TimeUnit.MINUTES);
        //将token返回前端
        return Result.success(token);
    }



    /**
     * 修改用户信息（用户名、密码）
     */
    @Override
    public Result editUser(User user) {
        String password = user.getPassword();
        user.setUpdateTime(LocalDateTime.now());
        user.setPassword(PasswordEncoder.encode(password));//密码加密
        userMapper.editUser(user);
        return Result.success();
    }

    /**
     * 根据用户账号获取用户信息
     * @return
     */
    @Override
    public Result getUserByAccount() {
        User user = UserHolder.getUser();
        Long account = user.getAccount();
        User user1 = userMapper.getUserByAccount(account);
        return Result.success(user1);
    }

    /**
     * 换绑手机
     * @param newPhone
     * @return
     */

    @Override
    public Result updatePhone(UpdatePhone newPhone) {
        //获取登录的用户
        User user = UserHolder.getUser();
        Long account = user.getAccount();
        String phone = newPhone.getNewPhone();
        //校验手机的验证码
        String CacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        String code = newPhone.getCode();
        if(CacheCode == null || !code.equals(CacheCode)){
            return Result.error("验证码有误或不存在！");
        }
        userMapper.updatePhone(phone,account);
        return Result.success("手机号修改成功！");
    }

}
